package com.hivekion.system.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.hivekion.common.core.SystemConstant;
import com.hivekion.common.entity.TreeNode;
import com.hivekion.common.exception.BusinessException;
import com.hivekion.common.redis.RedisUtil;
import com.hivekion.system.domain.SysStatisticsTargetClassic;
import com.hivekion.system.domain.vo.SysStatisticsTargetClassicCreateInputVo;
import com.hivekion.system.domain.vo.SysStatisticsTargetClassicUpdateInputVo;
import com.hivekion.system.domain.vo.SysStatisticsTargetClassicViewVo;
import com.hivekion.system.mapper.SysStatisticsTargetClassicMapper;
import com.hivekion.system.service.ISysStatisticsTargetClassicService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class SysStatisticsTargetClassicServiceImpl implements ISysStatisticsTargetClassicService {

      @Autowired
      private SysStatisticsTargetClassicMapper targetClassicMapper;

      @Autowired
      private RedisUtil redisUtil;

      @Override
      public Boolean checkTargetClassicNameUnique(String classicName, String classicId) {
	    LambdaQueryWrapper<SysStatisticsTargetClassic> StatisticsItemLambdaQueryWrapper =
		    Wrappers.lambdaQuery();
	    if (StringUtils.isNotEmpty(classicName)) {
		  StatisticsItemLambdaQueryWrapper.eq(SysStatisticsTargetClassic::getName, classicName);
	    }
	    if (StringUtils.isNotEmpty(classicId)) {
		  StatisticsItemLambdaQueryWrapper.eq(SysStatisticsTargetClassic::getId, classicId);
	    }
	    List<SysStatisticsTargetClassic> list =
		    targetClassicMapper.selectList(StatisticsItemLambdaQueryWrapper);
	    return list.size() > 0;
      }

      @Override
      public boolean create(SysStatisticsTargetClassicCreateInputVo inputVo) {
	    SysStatisticsTargetClassic item = new SysStatisticsTargetClassic();
	    BeanUtils.copyProperties(inputVo, item);

	    boolean bl = targetClassicMapper.insert(item) > 0;
	    if (bl) this.updateRedis();
	    return bl;
      }

      @Override
      public boolean update(SysStatisticsTargetClassicUpdateInputVo inputVo) {
	    SysStatisticsTargetClassic targetClassic = getTargetClassic(inputVo.getId());
	    BeanUtils.copyProperties(inputVo, targetClassic);
	    boolean bl = targetClassicMapper.updateById(targetClassic) > 0;
	    if (bl) this.updateRedis();
	    return bl;
      }

      private SysStatisticsTargetClassic getTargetClassic(String classicId) {
	    SysStatisticsTargetClassic targetClassic = targetClassicMapper.selectById(classicId);
	    if (targetClassic == null) {
		  throw new BusinessException(500, "getTargetClassic -> 未找到指标分类信息 deptId : " + classicId);
	    }
	    return targetClassic;
      }

      @Override
      public boolean delete(String StatisticsItemId) {

	    boolean bl = targetClassicMapper.deleteById(StatisticsItemId) > 0;
	    if (bl) this.updateRedis();
	    return bl;
      }

      @Override
      public List<SysStatisticsTargetClassicViewVo> getList() {
	    return buildViewVo(getParentClassics());
      }

      @Override
      public List<TreeNode> getTreeSelect() {
	    List<TreeNode> treeNodes = buildTreeNode(getParentClassics());
	    return treeNodes;
      }

      private List<SysStatisticsTargetClassicViewVo> buildViewVo(
	      List<SysStatisticsTargetClassic> list) {
	    List<SysStatisticsTargetClassicViewVo> nodes = new ArrayList<>();
	    if (list != null && list.size() > 0) {
		  list.forEach(
			  StatisticsItem -> {
				SysStatisticsTargetClassicViewVo vo =
					new SysStatisticsTargetClassicViewVo();
				BeanUtils.copyProperties(StatisticsItem, vo);

				vo.setChildren(null);
				List<SysStatisticsTargetClassicViewVo> vos =
					getChilderenVo(StatisticsItem.getId());
				if (vos != null && vos.size() > 0) {
				      vo.setChildren(vos);
				}
				nodes.add(vo);
			  });
	    }
	    return nodes;
      }

      private List<SysStatisticsTargetClassicViewVo> getChilderenVo(String parentId) {
	    List<SysStatisticsTargetClassic> list = getChildren(parentId);
	    return buildViewVo(list);
      }

      @Override
      public SysStatisticsTargetClassic getInfo(String targetId) {
	    SysStatisticsTargetClassic targetClassic = targetClassicMapper.selectById(targetId);
	    if (targetClassic == null) {
		  throw new BusinessException(500, "getInfo - > 未找到指标分类信息 targetId : " + targetId);
	    }
	    return targetClassic;
      }

      /*
       * redis 缓存数据
       * */
      public List<SysStatisticsTargetClassic> getAllList() {
	    if (redisUtil.hasKey(SystemConstant.redis_target_classic_data)) {
		  List<SysStatisticsTargetClassic> list =
			  JSON.parseArray(
				  redisUtil.get(SystemConstant.redis_target_classic_data).toString(),
				  SysStatisticsTargetClassic.class);
		  return list;
	    } else {
		  List<SysStatisticsTargetClassic> allClassic = targetClassicMapper.selectList(null);
		  redisUtil.set(SystemConstant.redis_target_classic_data, JSON.toJSONString(allClassic));
		  return allClassic;
	    }
      }

      private void updateRedis() {
	    List<SysStatisticsTargetClassic> allClassic = targetClassicMapper.selectList(null);
	    redisUtil.set(SystemConstant.redis_target_classic_data, JSON.toJSONString(allClassic));
      }

      private List<SysStatisticsTargetClassic> getParentClassics() {
	    List<SysStatisticsTargetClassic> parentClassics =
		    this.getAllList().stream()
			    .filter(x -> StringUtils.isEmpty(x.getParentId()))
			    .sorted(Comparator.comparing(SysStatisticsTargetClassic::getSortCode))
			    .collect(Collectors.toList());
	    return parentClassics;
      }

      private List<TreeNode> buildTreeNode(List<SysStatisticsTargetClassic> list) {
	    List<TreeNode> treeNodes = new ArrayList<>();
	    if (list != null && list.size() > 0) {
		  list.forEach(
			  classic -> {
				TreeNode node =
					new TreeNode(classic.getId(), classic.getName(), classic.getId());
				node.setData(classic);
				List<TreeNode> children = this.getChildrenNode(classic.getId());
				if (children != null && children.size() > 0) {
				      node.setLeaf(false);
				      node.setChildren(children);
				} else {
				      node.setLeaf(true);
				}
				treeNodes.add(node);
			  });
	    }
	    return treeNodes;
      }

      private List<TreeNode> getChildrenNode(String parentId) {
	    List<SysStatisticsTargetClassic> list = getChildren(parentId);
	    return buildTreeNode(list);
      }

      private List<SysStatisticsTargetClassic> getChildren(String parentId) {
	    LambdaQueryWrapper<SysStatisticsTargetClassic> classicLambdaQueryWrapper =
		    Wrappers.lambdaQuery();
	    classicLambdaQueryWrapper.eq(SysStatisticsTargetClassic::getParentId, parentId);
	    List<SysStatisticsTargetClassic> allList = this.getAllList();
	    List<SysStatisticsTargetClassic> list =
		    allList.stream()
			    .filter(t -> parentId.equals(t.getParentId()))
			    .sorted(Comparator.comparing(SysStatisticsTargetClassic::getSortCode))
			    .collect(Collectors.toList());
	    return list;
      }
}
